var inherits = require('util').inherits;
var EventEmitter = require('events').EventEmitter;

//数据缓存文件
fs.smartMkfileSync(__dirname + "/.db/data.cache." + database_name + ".json", "{}");
var _db = require("./.db/data.cache." + database_name + ".json");

//索引缓存文件
var _index;

var _ti;

process.on('uncaughtException', function(err) {
	console.error("进程未知错误，强行数据保存");
	console.error(err);
	foo.__updateCache();
});

function _on_db_exit(type) {
	return function() {
		console.error("进程意外中断，强行数据保存", type);
		foo.__updateCache();
		process.exit();
	}
};
process.on('SIGHUP', _on_db_exit("SIGHUP"));
process.on('SIGINT', _on_db_exit("SIGINT"));
process.on('SIGQUIT', _on_db_exit("SIGQUIT"));
process.on('SIGABRT', _on_db_exit("SIGABRT"));
process.on('SIGTERM', _on_db_exit("SIGTERM"));
var foo = {
	__updateCache: function(fileName) {
		console.group("save_data");
		console.time("parse_data");
		var _data = JSON._stringify(_db)
		console.timeEnd("parse_data");
		console.time("update_data");
		if (_data) {
			fs.writeFileSync(__dirname + "/.db/" + (fileName || "data.cache." + database_name + ".json"), _data);
		}
		console.timeEnd("update_data");
		console.groupEnd("save_data");
		//clearTimeout _ti
		_ti = null;
	},
	_updateCache: function() {
		clearTimeout(_ti);
		_ti = setTimeout(foo.__updateCache, 1000);
	},
	insert: function(db_name, obj, index) {
		db_name = db_name.toLowerCase();
		var table = _db[db_name];
		if (!table) {
			table = _db[db_name] = []
				//索引
			_index[db_name] = table._ = {};
		}
		var table_index = _index[db_name]
		if (!table_index[obj._id]) { //避免update后再insert
			table.push(obj);
		}
		if (obj._id || (obj._id = index)) {
			table_index[obj._id] = obj;
		}
		foo.emit("insert", db_name, obj);
		foo._updateCache( /*缓存到JSON文件中*/ );
	},
	find_by_id: function(db_name, id) {
		db_name = db_name.toLowerCase();
		var table_index = _index[db_name];
		if (table_index) {
			return table_index[id];
		}
	},
	find_one: function(db_name, obj) {
		db_name = db_name.toLowerCase();
		var table = _db[db_name];
		var result;
		if (table instanceof Array) {
			table.every(function(item_obj) {
				if (item_obj.has(obj)) {
					result = item_obj;
				} else {
					return true;
				}
			});
		}
		return result;
	},
	find_last_one: function(db_name, obj, sort_key, no_asc) {
		//默认是大~小
		db_name = db_name.toLowerCase();
		var table = _db[db_name];
		var result;
		if (table instanceof Array) {
			table = foo._sortBy(table, sort_key, !no_asc)
			for (var i = table.length - 1, item_obj; item_obj = table[i]; i -= 1) {
				if (item_obj.has(obj)) {
					result = item_obj;
					break;
				}
			}
		}
		return result;
	},
	find_list: function(db_name, obj, num) {
		num || (num = Infinity);
		db_name = db_name.toLowerCase();
		var table = _db[db_name];
		var result = [];
		if (table instanceof Array) {
			for (var i = 0, item_obj; item_obj = table[i]; i += 1) {
				if (item_obj.has(obj)) {
					result.push(item_obj)
				}
				if (result.length > num) {
					break
				}
			}
		}
		return result;
	},
	find_all: function(db_name) {
		db_name = db_name.toLowerCase();
		return _db[db_name] || [];
	},
	update: function(db_name, obj_index, obj) {
		db_name = db_name.toLowerCase();
		var old_obj = foo.find_by_id(db_name, obj_index);
		if (old_obj) {
			for (var key in obj) {
				if (obj.hasOwnProperty(key)) {
					old_obj[key] = obj[key];
				}
			}
			//更新索引的对象
			_index[db_name][old_obj._id] = old_obj;
			foo._updateCache( /*缓存到JSON文件中*/ );
		} else {
			foo.insert(db_name, obj, obj_index);
		}
	},
	remove: function(db_name, obj_index) {
		db_name = db_name.toLowerCase();
		var table = _db[db_name];
		var remover;
		table.every(function(obj, index) {
			if (obj._id === obj_index) {
				remover = obj;
				table.splice(index, 1);
				return false;
			}
			return true;
		});
		if (remover) {
			_index[db_name][obj_index] = null;
			foo._updateCache( /*缓存到JSON文件中*/ );
		}
	},
	remove_list: function(db_name, obj) {
		var remover_list = foo.find_list(db_name, obj);
		remover_list.forEach(function(remover) {
			foo.remove(db_name, remover._id);
		});
	},
	refreshIndex: function() {
		//重置索引，消除数组冗余
		_index = {};
		for (var dbname in _db) {
			if (_db.hasOwnProperty(dbname)) {
				var table = _index[dbname] = {};
				var _arr = _db[dbname];
				if (_arr instanceof Array) {
					for (var i = 0, len = _arr.length; i < len; i += 1) {
						var obj = _arr[i];
						if (!obj) {
							continue;
						}
						var old_obj = table[obj._id];
						if (old_obj) {
							//删除冗余数据
							_arr.splice(_arr.indexOf(old_obj), 1);
							i -= 1;
						}
						table[obj._id] = obj;
					}
				}
			}
		}
	},
	//排序函数
	_sortBy: require("./skill").sortBy,
	_db: _db
};
foo.__proto__ = EventEmitter.prototype;
EventEmitter.call(foo);
module.exports = foo;